#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/wait.h>

#include "ic.h"
#include "config.h"

typedef struct {
	GtkStatusIcon *icon;
	GtkMenu *menu;
	int timer_id;
	GtkWidget *window;
	GtkWidget *label;
	config_t config;
} Tray ;

static int radio_pid = 0;
void sigchld_handler(int signal)
{
	int status;
	waitpid(radio_pid, &status, 0);
	if(WIFEXITED(status) || WIFSIGNALED(status))
		radio_pid = 0;
}

static void tray_free(Tray *me)
{
	if(me->window)
		gtk_widget_destroy(me->window);
	g_object_unref(me->menu);
	g_object_unref(me->icon);
	free(me);
}

static gboolean tray_update_balance(void *data)
{
	GError *err = NULL;
	report_t r;
	int res = 0;
	Tray *me = data;
	char *msg = NULL;

	res = ic_get_report(me->config.login, me->config.password, &r, &err);
	if(res){
		msg = g_strdup_printf("%0.2f руб.\n%0.0f Mb\nBlocked:%s", r.balance,
							  r.traffic, r.blocked?"Yes":"No");
	}
	else{
		msg = g_strdup(err->message);
	}

	gtk_status_icon_set_tooltip(me->icon, msg);
	if(me->label)
		gtk_label_set_text(GTK_LABEL(me->label), msg);

	g_free(msg);

	return TRUE;
}

inline gboolean ut_update_props(gpointer data)
{
	Tray *me = data;
	if(me->timer_id)
		g_source_remove(me->timer_id);
	me->timer_id = g_timeout_add(me->config.delay * 1000, tray_update_balance, me);
	tray_update_balance(me);
	
	return FALSE;
}

static void tray_show_menu(Tray *me, guint button, guint activate_time)
{
	gtk_menu_popup(me->menu, NULL, NULL, NULL, NULL, button, activate_time);
}

extern int kill(int pid, int sig);
static void tray_play_station(GtkMenuItem *item, Tray *me)
{
	char* station = g_object_get_data(G_OBJECT(item), "station");
	if(radio_pid){
		kill(radio_pid, SIGTERM);
		waitpid(radio_pid, NULL, 0);
	}
	radio_pid = ic_radio_play(station, "mplayer", NULL);
}

static void tray_stop_station()
{
	kill(radio_pid, SIGTERM);
}

static void tray_reset_window(Tray *me)
{
	me->window = NULL;
	me->label = NULL;
}

static void tray_show_window(Tray *me)
{
	gtk_status_icon_set_from_stock(me->icon, GTK_STOCK_CONNECT);

	if(me->window){
		gtk_widget_destroy(me->window);
	}
	else{
		me->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		me->label = gtk_label_new("");
		gtk_window_set_default_size(GTK_WINDOW(me->window), 150,50);
		gtk_window_set_keep_above(GTK_WINDOW(me->window), TRUE);
		gtk_container_add(GTK_CONTAINER(me->window), me->label);
		g_signal_connect_swapped(me->label, "destroy", G_CALLBACK(tray_reset_window), me);
		g_signal_connect_swapped(me->window, "destroy", G_CALLBACK(tray_reset_window), me);
		gtk_widget_show_all(me->window);
		tray_update_balance(me);
	}
}

static void tray_show_configure(Tray *me)
{
	config_run_dialog(&me->config, (ConfigCallback)ut_update_props, me);
}

static Tray* tray_new()
{
	GtkWidget *item = NULL;
	Tray *me = calloc(sizeof(*me), 1);

	//create some needed objects
	me->icon = gtk_status_icon_new_from_stock(GTK_STOCK_NETWORK);
	me->menu = (GtkMenu*)gtk_menu_new();
	g_object_ref_sink(me->menu);
	
	//configure item
	item = gtk_menu_item_new_with_label("Configure");
	g_signal_connect_swapped(item, "activate", G_CALLBACK(tray_show_configure), me);
	gtk_menu_append(me->menu, item);

	//radio list menu
	char **rlist = ic_radio_get_list(NULL);
	if(rlist && *rlist){
		//create item radiolist
		item = gtk_menu_item_new_with_label("RadioList");
		gtk_menu_append(me->menu, item);

		//create and fill submenu
		GtkMenu *rmenu = (GtkMenu*)gtk_menu_new();
		GSList *group = NULL;
		for(int i = 0; rlist[i]; i++){
			char http[] = "http://";
			GtkWidget *subitem = gtk_radio_menu_item_new_with_label(group, rlist[i]+sizeof(http)-1);
			group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (subitem));
			g_object_set_data(G_OBJECT(subitem), "station", rlist[i]);
			gtk_menu_append(rmenu, subitem);
			g_signal_connect(subitem, "activate", G_CALLBACK(tray_play_station), me);
		}

		//add submenu to rlist item
		gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), GTK_WIDGET(rmenu));
	}

	//stop item
	item = gtk_menu_item_new_with_label("Stop");
	g_signal_connect_swapped(item, "activate", G_CALLBACK(tray_stop_station), me);
	gtk_menu_append(me->menu, item);

	//quit item
	item = gtk_menu_item_new_with_label("Quit");
	g_signal_connect_swapped(item, "activate", G_CALLBACK(gtk_main_quit), me);
	gtk_menu_append(me->menu, item);
	
	//conect signals
	g_signal_connect_swapped(me->icon, "popup-menu", G_CALLBACK(tray_show_menu), me);
	g_signal_connect_swapped(me->icon, "activate", G_CALLBACK(tray_show_window), me);	

	//init values
	config_load(&me->config, NULL);
	g_idle_add(ut_update_props, me);

	gtk_widget_show_all(GTK_WIDGET(me->menu));

	return me;
}

int main(int argc, char *argv[])
{
	gtk_init(&argc, &argv);

	Tray *tray = tray_new();
	signal(SIGCHLD, sigchld_handler);

	gtk_main();

	tray_free(tray);
	tray_stop_station();

	return 0;
}
